package org.japo.java.entities;

import java.io.Serializable;

/**
 *
 * @author José A. Pacheco Ondoño - joanpaon@gmail.com
 */
public class Nif implements Serializable {

    // Atributos
    private int dni;
    private char letra;

    // Constantes
    public static final String LETRAS = "TRWAGMYFPDXBNJZSQVHLCKE";

    public Nif() {
        inicializarNif();
    }

    public Nif(int dni) {
        if (validarDni(dni)) {
            this.dni = dni;
            this.letra = calcularLetra(dni);
        } else {
            inicializarNif();
        }
    }

    public int getDni() {
        return dni;
    }

    public void setDni(int dni) {
        if (validarDni(dni)) {
            this.dni = dni;
            this.letra = calcularLetra(dni);
        }
    }

    public char getLetra() {
        return letra;
    }

    public static char calcularLetra(int dni) {
        return LETRAS.charAt(dni % 23);
    }

    public static boolean validarNif(int dni, char letra) {
        return letra == calcularLetra(dni);
    }

    @Override
    public String toString() {
        return String.format("%08d%c", dni, letra);
    }

    @Override
    public boolean equals(Object o) {
        //  Semaforo de análisis
        boolean analisisOK = false;

        // Comprueba polimorfismo
        if (o instanceof Nif) {
            // Convierte la referencia
            Nif nif = (Nif) o;
            
            // Obtiene DNI
            int dniAct = nif.getDni();
            
            // Obtiene letra
            char letraAct = nif.getLetra();
            
            // Actualiza el semáforo
            analisisOK = dni == dniAct && letra == letraAct;
        }
        
        // Devuelvel el resultado del análisis
        return analisisOK;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 73 * hash + this.dni;
        return hash;
    }

    public static Nif parseNif(String txtNif) throws Exception {
        // Referencia al objeto generado
        Nif nif;
        
        // Obtiene el texto DNI del texto NIF
        String txtDni = txtNif.substring(0, 8);
            
        // Obtiene el número de DNI
        int dni = Integer.parseInt(txtDni);
            
        // Genera un nuevo objeto Nif
        nif = new Nif(dni);
        
        // Devuelve el objeto generado
        return nif;
    }

    public static boolean validarDni(int dni) {
        return dni >= 0 && dni <= 99999999;
    }

    private void inicializarNif() {
        this.dni = 0;
        this.letra = 'T';
    }
}
